_package("alz.core");

_import("alz.core.EventTarget");
_import("alz.core.TableIndex");
_import("alz.core.TableFilter");
_import("alz.core.DataChangeEvent");

/**
 * 元数据表
 */
_class("MetaTable", EventTarget, function(){
	this._init = function(pid){
		_super._init.call(this);
	//this._parent = null;
	//this._listeners = [];     //数据监听组件列表
		this._conf = null;        //配置信息
		this._id = "";            //数据表ID标识
		this._path = "";          //[TODO]非通用属性
		this._primaryKey = pid || "id";  //主键
		this._hash = {};          //(哈希表)数据列表
		this._list = null;        //数据数组(当含有排序信息后，可以当作主索引使用)
		this._hashIndex = {};     //索引哈希(每个元素是一个TableIndex对象)
		this._filters = {};       //过滤器及过滤器对应的结果
		this._maxId = 0;          //最大ID
	};
	this.create = function(parent, id, path){
		var index = this.createIndex("+" + this._primaryKey);
		this._list = index.getList();  //主索引
		this._parent = parent;
		this._id = id;
		this._path = path;
	};
	this.dispose = function(){
		for(var k in this._filters){
			this._filters[k] = null;
			delete this._filters[k];
		}
		for(var k in this._hashIndex){
			this._hashIndex[k].dispose();
			delete this._hashIndex[k];
		}
		/*
		for(var i = 0, len = this._list.length; i < len; i++){
			this._list[i] = null;
		}
		*/
		this._list = null;
		for(var k in this._hash){
			delete this._hash[k];
		}
		//this._parent = null;
		_super.dispose.apply(this);
	};
	this.exists = function(id){
		return id in this._hash;
	};
	this.setConf = function(v){
		this._conf = v;
	};
	this.getId = function(){
		return this._id;
	};
	this.getPrimaryKey = function(){
		return this._primaryKey;
	};
	this.getMaxId = function(){
		return this._maxId;
	};
	this.getItem = function(id){
		return this._hash[id];
	};
	this.getList = function(){
		return this._list;
	};
	this.getListByFilter = function(filter){
		var arr = [];
		for(var i = 0, len = this._list.length; i < len; i++){
			var item = this._list[i];
			if(filter(item)){
				arr.push(item);
			}
			item = null;
		}
		return arr;
	};
	this.getIndex2 = function(key){
		if(key in this._hashIndex){
			return this._hashIndex[key];
		}else{
			return this.createIndex(key);
		}
	};
	/**
	 * 创建一个索引
	 * @param {String} 要索引的key
	 * @return {TableIndex}
	 */
	this.createIndex = function(key){
		var ti = new TableIndex();
		ti.create(this, key);
		this._hashIndex[key] = ti;
		return ti;
	};
	/**
	 * 创建一个过滤器
	 * @param {String} key 排序的字段
	 * @param {Function} filter 过滤器函数
	 * @return {TableFilter}
	 */
	this.createFilter = function(key, filter){
		var tf = new TableFilter();
		tf.create(this, key, filter);
		this._filters[key] = tf;
		return tf;
	};
	/*
	this.insertPos = function(list, item, key){
		var i;
		for(i = 0, len = list.length; i < len; i++){
			if(item[key] > list[i][key]){
				break;
			}
		}
		return i;
	};
	this.dataFormat = function(data){
		this.insertRecords(data);
	};
	*/
	/**
	 * 格式化列表数据
	 * @param {Array} dataList 数据列表
	 * @param {Boolean} checkRemove 是否检查并处理记录的删除
	 */
	this.dataFormat = function(dataList, checkRemove){
		dataList = dataList || [];
		var hash = {};  //for dataList
		for(var i = 0, len = dataList.length; i < len; i++){
			var record = dataList[i];
			var id = record[this._primaryKey];
			hash[id] = true;  //数组转换成哈希，加速后面删除逻辑的访问
			if(!(id in this._hash)){  //如果记录不存在，则添加
				this.insertRecord(record);
			}else{
				this.updateRecord(record);
			}
			record = null;
		}
		if(checkRemove){  //是否检查已删除记录？
			for(var k in this._hash){  //处理已删除联系人的逻辑
				if(!(k in hash)){
					this.deleteRecord(k);
				}
			}
		}
		hash = null;
	};
	/**
	 * 添加一条记录
	 */
	this.insertRecord = function(data, list){
		var id = data[this._primaryKey];
		if(/^\d+$/.test(id)){
			id = data[this._primaryKey] = parseInt(id);  //默认主键数字型
		}
		//1)保证主键(id)唯一性
		if(id in this._hash){  //如果已经存在，忽略
			runtime.warning("新增记录(type=" + this._id + ")已经存在id=" + id);
		}else{  //新增
			var item = data;  //runtime.clone(data);
			if(id > this._maxId){
				this._maxId = id;
			}
			this._hash[id] = item;  //2)存储到hash中
			//3)更新主索引和其他索引
			//var n = this.insertPos(this._list, item, this._primaryKey);
			for(var k in this._hashIndex){
				this._hashIndex[k].updateIndex("add", item);
			}
			//[TODO]4)更新过滤器
			if(list){  //批量添加忽略数据监听
				//this._list.push(item);
				list.push(item);
			}else{
				this.dispatchEvent(new DataChangeEvent(this._id + "_add", item));
			}
		}
		/* for test
		function dump(list){
			var sb = [];
			for(var i = 0, len = list.length; i < len; i++){
				sb.push(list[i][this._primaryKey]);
			}
			runtime.log(sb.join(","));
		}
		dump(this._list);
		*/
		return this._hash[id];
	};
	/**
	 * 添加N条记录
	 */
	this.insertRecords = function(data){
		var list = [];
		for(var i = 0, len = data.length; i < len; i++){
			var record = data[i];
			this.insertRecord(record, list);
		}
		/* for test
		var n = 0;
		for(var i = 0, len = data.length; i < len;){
			if(n % 2 == 1){
				this.insertRecord(data[i], list);
				i++;
			}else{
				this.insertRecord(data[len - 1], list);
				len--;
			}
			n++;
		}
		*/
		this.dispatchEvent(new DataChangeEvent(this._id + "_adds", list));
	};
	/**
	 * 更新一条记录
	 */
	this.updateRecord = function(data){
		var id = data[this._primaryKey];
		if(/^\d+$/.test(id)){
			id = data[this._primaryKey] = parseInt(id);  //默认主键数字型
		}
		if(!(id in this._hash)){  //如果不存在
			runtime.error("[MetaTable::updateRecord]不存在要更新的记录id=" + id);
		}else{
			var item = this._hash[id];
			for(var k in data){  //只更新第一层属性
				item[k] = data[k];  //更新一个属性
			}
			for(var k in this._hashIndex){
				this._hashIndex[k].updateIndex("mod", item);
			}
			this.dispatchEvent(new DataChangeEvent(this._id + "_mod", item));
			item = null;
		}
	};
	/**
	 * 删除一条记录
	 * @param {Number|String} 记录的主键id
	 */
	this.deleteRecord = function(id){
		if(!(id in this._hash)){
			runtime.error("[MetaTable::deleteRecord]不存在要删除的记录id=" + id);
		}else{
			var item = this._hash[id];
			//this._parentModel.removeContact(item);
			this.dispatchEvent(new DataChangeEvent(this._id + "_del", item));
			for(var k in this._hashIndex){
				this._hashIndex[k].updateIndex("del", item);
			}
			delete this._hash[id];  //删除
			item = null;
		}
	};
	/**
	 * 删除N条记录
	 * @param ids {Array}
	 */
	this.deleteRecords = function(ids){
		for(var i = 0, len = ids.length; i < len; i++){
			this.deleteRecord(ids[i]);
		}
	};
	/**
	 * 针对已经存在的记录派发相应的事件
	 */
	this.dispatchExistRecords = function(){
		if(this._list.length > 0){
			var ev = new DataChangeEvent(this._id + "_adds", this._list);
			this.dispatchEvent(ev);
		}
		for(var k in this._hashIndex){
			this._hashIndex[k].dispatchExistRecords();
		}
	};
	/**
	 * 执行回调函数
	 * @param {Number} cbid 回调函数编号
	 * @param {JsonObject} data 传递给回调函数的参数
	 */
	this.callback = function(cbid, data){
		runtime._task.execute(cbid, [data]);
	};
});